extends Node
# ---------------------变量声明-----------------------#
signal cameraShake(amount:float)

# 存档路径
const SAVE_PATH:="user://data.sav"
# 设置路径
const CONF_PATH:='user://config.ini'

# 场景名称=>{
# enemiesAlive=>[敌人的路径]
# }
var worldState:={}

@onready var playerStats:Stats=$PlayerStats
@onready var mask:ColorRect=$ColorRect
@onready var animation:AnimationPlayer=$AnimationPlayer
@onready var A:AnimationPlayer=$AnimationPlayer
@onready var defaultPlayer:=playerStats.toDict()
# 暂停界面
@onready var pauseScreen:Control=$PauseScreen
# 死亡界面
@onready var deadScreen:Control=$DeadScreen
# ---------------------生命周期-----------------------#
func _ready()->void:
	loadConfg()
	pauseScreen.update()

# 监听esc按键
func _unhandled_input(event: InputEvent) -> void:
	if event.is_action_pressed("pause"):
		pauseScreen.showPause()

# ---------------------响应函数-----------------------#
# 切换场景
func changeScene(path:String,params:={})->void:
	var duration:=params.get('duration',0.5) as float
	var tree:=get_tree()
	tree.paused=true
	await transIn(duration)

	if tree.current_scene is Map:
		var oldName:=curSceneName()
		# 缓存场景数据
		worldState[oldName]=tree.current_scene.toDict()

	tree.change_scene_to_file(path)
	await tree.tree_changed

	if tree.current_scene is Map:
		var newName :=curSceneName()
		# 载入场景数据
		if newName in worldState:
			tree.current_scene.fromDict(worldState[newName])
		# 放置玩家
		putPlayer(tree,params)

	tree.paused=false
	transOut(duration)

# 转场入(展开黑幕)
func transIn(duration):
	# 设置暂停模式，取消之前的tween动画
	var tween:=create_tween().set_pause_mode(Tween.TWEEN_PAUSE_PROCESS)
	tween.tween_property(mask.material,"shader_parameter/cutoff",0,duration)
	await tween.finished
#	animation.play("转入")
#	await animation.animation_finished

# 转场出(收起黑幕)
func transOut(duration):
	var tween:=create_tween().set_pause_mode(Tween.TWEEN_PAUSE_PROCESS)
	tween.tween_property(mask.material,"shader_parameter/cutoff",1,duration)
#	animation.play("转出")
#	animation.animation_finished

# 放置玩家
func putPlayer(tree,params):
	if 'entryPoint' in params:
		for node in tree.get_nodes_in_group('entryPoints'):
			if node.name==params.entryPoint:
				tree.current_scene.updatePlayer(node.position,node.direction)
				break
	if 'position' in params and 'direction' in params:
		tree.current_scene.updatePlayer(params.position,params.direction)

	if 'init' in params:
		params.init.call()

# 获取当前场景名称
func curSceneName()->String:
	return get_tree().current_scene.scene_file_path.get_file().get_basename()

# 游戏存档
func saveGame()->void:
	# 同步当前场景数据
	var scene=get_tree().current_scene
	var sceneName:=curSceneName()
	worldState[sceneName]=scene.toDict()
	# 生存的敌人及位置；玩家统计信息；当前加载场景的路径
	var data:={
		worldState=worldState,
		stats=playerStats.toDict(),
		scene=scene.scene_file_path,
		player={
			direction=scene.player.direction,
			position={
				x=scene.player.global_position.x,
				y=scene.player.global_position.y,
			},
		}
	}
	# 按文件路径写入数据
	var json:=JSON.stringify(data)
	var file:=FileAccess.open(SAVE_PATH,FileAccess.WRITE)
	if not file:return
	file.store_string(json)

# 游戏读档
func loadGame()->void:
	var file:=FileAccess.open(SAVE_PATH,FileAccess.READ)
	if not file:return
	var json:=file.get_as_text()
	var data:=JSON.parse_string(json) as Dictionary

	changeScene(data.scene,{
		direction=data.player.direction,
		position=Vector2(
			data.player.position.x,
			data.player.position.y
		),
		init=func():
			worldState=data.worldState
			playerStats.fromDict(data.stats)
	})

# 新游戏
func newGame()->void:
	changeScene("res://场景/地图/森林/forest.tscn",{
		duration=1,
		init=func():
			worldState={}
			playerStats.fromDict(defaultPlayer)
	})

# 回到标题页
func backTitle()->void:
	changeScene("res://场景/界面/游戏开始/titleScreen.tscn",{ duration=1 })

# 判断存档存在
func hasSave()->bool:
	return FileAccess.file_exists(SAVE_PATH)

# 保存配置
func saveConfg()->void:
	var config:=ConfigFile.new()
	for key in Sounds.Bus.size():
		config.set_value('audio',Sounds.Bus[key].name,Sounds.getVolume(key))

	config.save(CONF_PATH)

# 加载配置
func loadConfg()->void:
	var config:=ConfigFile.new()
	config.load(CONF_PATH)

	for key in Sounds.Bus.size():
		Sounds.setVolume(key,config.get_value('audio',Sounds.Bus[key].name,Sounds.Bus[key].value))

func shakeCamera(amount:float)->void:
	cameraShake.emit(amount)
